'''
    GM(1,1)模型
例题：
    北方某城市的道路交通噪声平均声级预测
'''
import numpy as np
import pandas as pd
import sympy

def get_data():
    '''
    读取数据
    :return:
    '''
    data=pd.read_csv('15_2.csv')
    return np.array(data['year']),np.array(data['leq'])

def grade_ratio_judgment(data):
    '''
    级比判断
    :param data:
    :return:
    '''
    grade=[]
    for i,j in zip(data[:len(data)-1],data[1:]):
        grade.append(i/j)
    return np.array([min(grade),max(grade)])

def data_accumulate(data):
    '''
    原始数据累加
    :param data:
    :return:
    '''
    data_sum=[]
    for i in range(0,len(data)):
        data_sum.append(sum(data[:i+1]))
    return np.array(data_sum)

def build_model(data):
    '''
    模型拟合
    :param data:
    :return:
    '''
    accumulate_data=data_accumulate(data)
    B=np.mat([[(-1/2)*(accumulate_data[i]+accumulate_data[i+1]),1] for i in range(len(accumulate_data)-1)])
    Y=np.mat([i for i in data[1:]]).T
    #print(B)
    #print(Y)
    # 计算出参数a和b
    u=np.linalg.pinv(B.T*B)*B.T*Y
    # 这个函数是计算出累加值
    fun=lambda k:(data[0]-u[1]/u[0])*np.e**float(-u[0]*k)+u[1]/u[0]
    return fun


if __name__=='__main__':
    year,leq=get_data()
    #print(grade_ratio_judgment(leq))
    #print(data_accumulate(leq))
    #print(build_model(leq))
    fun=build_model(leq)
    print("真实值：",leq)
    print("预测值：",[float(fun(i+1)-fun(i)) if i>0 else float(fun(i)) for i in range(0,len(leq))])